using System;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Threading.Tasks;
using System.Collections.Generic;
using Microsoft.EntityFrameworkCore;
using Abp.AutoMapper;
using Abp.Authorization;
using Abp.Domain.Repositories;
using Abp.Application.Services.Dto;
using Abp.Linq.Extensions;
using Yozeev.SystemConfig.Dtos;
using Yozeev.SystemConfig.DomainService;
using Abp.Domain.Entities.Auditing;
using Yozeev.SystemConfig.SystemRecord.Dtos;
using Yozeev.Common;

namespace Yozeev.SystemConfig
{
	/// <summary>
	/// Power应用层服务的接口实现方法  
	///</summary>
	[AbpAuthorize]
    public class PowerAppService : YozeevAppServiceBase, IPowerAppService
    {
        private readonly IRepository<Power, Guid> _entityRepository;

		private readonly IRepository<Menu, Guid> _menuRep;


        private readonly IPowerManager _entityManager;

		private readonly IQueryHelper _queryHelper;

		/// <summary>
		/// 构造函数 
		///</summary>
		public PowerAppService(
        IRepository<Power, Guid> entityRepository
        ,IPowerManager entityManager
		, IRepository<Menu, Guid> menuRep
		, IQueryHelper queryHelper
		)
        {
            _entityRepository = entityRepository; 
             _entityManager=entityManager;
			_menuRep = menuRep;
			_queryHelper = queryHelper;
		}


        /// <summary>
        /// 获取Power的分页列表信息
        ///</summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<PagedResultDto<PowerListDto>> GetPaged(GetPowersInput input)
		{

			var expression = _queryHelper.WhereExp<Power>(input.queryData);
			var query = from powers in _entityRepository.GetAll().Where(expression)
						join menus in _menuRep.GetAll()
						on powers.MenuId equals menus.Id
                        select new PowerListDto
						{
							MenuId = powers.MenuId,
							Menu = menus,
							MenuPath = powers.MenuPath,
							PowerCode = powers.PowerCode,
							PowerName = powers.PowerName,
							Method = powers.Method,
							Params = powers.Params,
							GroupName = powers.GroupName,
							Sort = powers.Sort,
							IocName = powers.IocName,
							IocClassName = powers.IocClassName,
							Category = powers.Category,
							IsEnabled = powers.IsEnabled,
							CreationTime = powers.CreationTime,
							CreatorUserId = powers.CreatorUserId,
							Id = powers.Id,
						};
            
			var count = await query.CountAsync();

			var entityList = await query
					.OrderBy(input.Sorting).AsNoTracking()
					.PageBy(input)
					.ToListAsync();

			// var entityListDtos = ObjectMapper.Map<List<PowerListDto>>(entityList);
			var entityListDtos =entityList.MapTo<List<PowerListDto>>();

			return new PagedResultDto<PowerListDto>(count,entityListDtos);
		}


		/// <summary>
		/// 通过指定id获取PowerListDto信息
		/// </summary>
		public async Task<PowerListDto> GetById(EntityDto<Guid> input)
		{
			var entity = await _entityRepository.GetAsync(input.Id);

		    return entity.MapTo<PowerListDto>();
		}

		/// <summary>
		/// 获取编辑 Power
		/// </summary>
		/// <param name="input"></param>
		/// <returns></returns>
		public async Task<GetPowerForEditOutput> GetForEdit(NullableIdDto<Guid> input)
		{
			var output = new GetPowerForEditOutput();
			PowerEditDto editDto;

			if (input.Id.HasValue)
			{
				var entity = await _entityRepository.GetAsync(input.Id.Value);

				editDto = entity.MapTo<PowerEditDto>();

				//powerEditDto = ObjectMapper.Map<List<powerEditDto>>(entity);
			}
			else
			{
				editDto = new PowerEditDto();
			}

			output.Power = editDto;
			return output;
		}


		/// <summary>
		/// 添加或者修改Power的公共方法
		/// </summary>
		/// <param name="input"></param>
		/// <returns></returns>
		public async Task CreateOrUpdate(CreateOrUpdatePowerInput input)
		{
			if (input.Power.Id.HasValue)
			{
				await Update(input.Power);
			}
			else
			{
				await Create(input.Power);
			}
		}

		/// <summary>
		/// 新增Power
		/// </summary>
		protected virtual async Task<PowerEditDto> Create(PowerEditDto input)
		{
			//TODO:新增前的逻辑判断，是否允许新增

            // var entity = ObjectMapper.Map <Power>(input);
            var entity=input.MapTo<Power>();
			

			entity = await _entityRepository.InsertAsync(entity);
			return entity.MapTo<PowerEditDto>();
		}

		/// <summary>
		/// 编辑Power
		/// </summary>
		protected virtual async Task Update(PowerEditDto input)
		{
			//TODO:更新前的逻辑判断，是否允许更新

			var entity = await _entityRepository.GetAsync(input.Id.Value);
			input.MapTo(entity);

			// ObjectMapper.Map(input, entity);
		    await _entityRepository.UpdateAsync(entity);
		}

		/// <summary>
		/// 删除Power信息的方法
		/// </summary>
		/// <param name="input"></param>
		/// <returns></returns>
		public async Task Delete(EntityDto<Guid> input)
		{
			//TODO:删除前的逻辑判断，是否允许删除
			await _entityRepository.DeleteAsync(input.Id);
		}

		/// <summary>
		/// 批量删除Power的方法
		/// </summary>
		public async Task BatchDelete(List<Guid> input)
		{
			// TODO:批量删除前的逻辑判断，是否允许删除
			await _entityRepository.DeleteAsync(s => input.Contains(s.Id));
		}


		/// <summary>
		/// 导出Power为excel表,等待开发。
		/// </summary>
		/// <returns></returns>
		//public async Task<FileDto> GetToExcel()
		//{
		//	var users = await UserManager.Users.ToListAsync();
		//	var userListDtos = ObjectMapper.Map<List<UserListDto>>(users);
		//	await FillRoleNames(userListDtos);
		//	return _userListExcelExporter.ExportToFile(userListDtos);
		//}

		/// <summary>
		/// 批量增加权限
		/// </summary>
		/// <param name="menuId">菜单Id</param>
		/// <param name="powerCodeList"></param>
		/// <returns></returns>
		public async Task BatchCreate(Guid menuId,List<string> powerCodeList)
		{
			var menu = _menuRep.GetAll().FirstOrDefault(m => m.Id == menuId);
			if (menu == null)
				throw new Exception("查无此菜单");
			foreach (var powerCode in powerCodeList)
			{
				var power = new Power()
				{
					MenuId = menuId,
					PowerCode = powerCode,
					MenuPath = menu.NavigateUrl,
					IsEnabled = true,
					CreatorUserId = AbpSession.UserId,
					CreationTime = DateTime.Now,
					Sort = powerCodeList.IndexOf(powerCode),
					IocClassName = "anticon anticon-api",
					IocName = "anticon anticon-api",
				};
				switch (powerCode)
				{
					case "ownmenu":power.PowerName = "拥有菜单";power.Category = PowerTypeEnum.MENU; break;
					case "viewown": power.PowerName = "仅查看自己的数据"; power.Category = PowerTypeEnum.Data; break;
					case "viewownorgan": power.PowerName = "仅查看所在机构的数据"; power.Category = PowerTypeEnum.Data; break;
					case "viewsuborgan": power.PowerName = "仅查看所在机构的子机构的数据"; power.Category = PowerTypeEnum.Data; break;
					case "viewallorgan": power.PowerName = "查看所有机构的数据"; power.Category = PowerTypeEnum.Data; break;
					case "CreateOrUpdate": power.PowerName = "添加或者修改"; power.Category = PowerTypeEnum.OPERATE; break;
					case "GetForEdit": power.PowerName = "获取编辑"; power.Category = PowerTypeEnum.OPERATE; break;
					case "Delete": power.PowerName = "删除"; power.Category = PowerTypeEnum.OPERATE; break;
					case "BatchDelete": power.PowerName = "批量删除"; power.Category = PowerTypeEnum.OPERATE; break;
					case "GetToExcel": power.PowerName = "导出excel表"; power.Category = PowerTypeEnum.OPERATE; break;
					default: break;
				}
				if (string.IsNullOrWhiteSpace(power.PowerName))
					throw new Exception("无效权限名称");
				await _entityRepository.InsertAndGetIdAsync(power);
			}
		}

		/// <summary>
		/// 取票支持类型接口
		/// </summary>
		/// <param name="userId">自助机用户ID</param>
		/// <returns></returns>
		public async Task<List<GetTicketPower>> MachineGetTicketType(long userId)
		{
			return _entityManager.GetPowerByUserId(userId)
				.Select(p => new GetTicketPower 
				{ 
					GetTicketTypeId = p.PowerCode, 
					GetTicketTypeName = p.PowerName
				})
				.ToList();
		}
    }
}


